package cn.lingyangwl.framework.data.mate.fieldbind;

import cn.lingyangwl.framework.data.mate.fieldbind.inter.IFieldBindAnnotationDataGetter;
import cn.lingyangwl.framework.data.mate.fieldbind.model.FieldDefine;
import cn.lingyangwl.framework.tool.core.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 设置目标字段值处理器
 * @param <T> 目标字段类型
 * @author shenguangyang
 */
public interface SetTargetFieldValueHandler<T> {
    /**
     * 设置目标字段值<br>
     * 每个对象的属性都会调用一次, 比如需要处理一个对象, 其中有10个字段需要进行字段绑定操作, 那么就会被调用10次
     *
     * @param metaObject     处理的对象元数据
     * @param fieldDefine 字段定义数据, 可以获取当前处理的字段上自定义的字段绑定注解数据, 来自
     *                       {@link IFieldBindAnnotationDataGetter#initFieldBindAnnotation(Annotation)} (Annotation)} ()}
     *                       方法的返回值
     */
    void setValue(Collection<Object> valueList, List<?> codeList, MetaObject metaObject, FieldDefine fieldDefine);

    @Component
    class StringType implements SetTargetFieldValueHandler<String> {

        @Override
        public void setValue(Collection<Object> valueList, List<?> codeList, MetaObject metaObject, FieldDefine fieldDefine) {
            String targetValue = valueList.stream().map(String::valueOf).collect(Collectors.joining());
            metaObject.setValue(fieldDefine.getTargetField().getName(), targetValue);
        }
    }

    @Component
    class StringArray implements SetTargetFieldValueHandler<String[]> {

        @Override
        public void setValue(Collection<Object> valueList, List<?> codeList, MetaObject metaObject, FieldDefine fieldDefine) {
            String[] targetValue = valueList.stream().map(String::valueOf).toArray(String[]::new);
            metaObject.setValue(fieldDefine.getTargetField().getName(), targetValue);
        }
    }

    @Component
    class StringList implements SetTargetFieldValueHandler<List<String>> {

        @Override
        public void setValue(Collection<Object> valueList, List<?> codeList, MetaObject metaObject, FieldDefine fieldDefine) {
            Object targetValue = valueList.stream().map(String::valueOf).collect(Collectors.toList());
            metaObject.setValue(fieldDefine.getTargetField().getName(), targetValue);
        }
    }

    @Component
    class StringSet implements SetTargetFieldValueHandler<Set<String>> {

        @Override
        public void setValue(Collection<Object> valueList, List<?> codeList, MetaObject metaObject, FieldDefine fieldDefine) {
            Object targetValue = valueList.stream().map(String::valueOf).collect(Collectors.toSet());
            metaObject.setValue(fieldDefine.getTargetField().getName(), targetValue);
        }
    }

}
